package edu.neu.ecommerceplatform.service.Impl;

import edu.neu.ecommerceplatform.Exception.ResourceNotFoundException;
import edu.neu.ecommerceplatform.mapper.CategoryMapper;
import edu.neu.ecommerceplatform.mapper.ProductMapper;
import edu.neu.ecommerceplatform.model.Category;
import edu.neu.ecommerceplatform.model.Product;
import edu.neu.ecommerceplatform.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
import edu.neu.ecommerceplatform.dto.CategorySalesDto;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class ProductServiceImpl implements ProductService {
    private static final Logger logger = LoggerFactory.getLogger(ProductServiceImpl.class);
    private final ProductMapper productMapper;
    private final CategoryMapper categoryMapper;
    @Autowired
    public ProductServiceImpl(ProductMapper productMapper, CategoryMapper categoryMapper) {
        this.productMapper = productMapper;
        this.categoryMapper = categoryMapper;
    }

    @Override
    public List<Product> getAllProducts() {
        return productMapper.findAll();
    }

    @Override
    public Product getProductById(Integer id) {
        logger.info("正在通过ID获取商品: {}", id);
        Product product = productMapper.findById(id);
        if (product == null) {
            logger.warn("未找到商品 id:{}", id);
            throw new ResourceNotFoundException("Product", "id", id);
        }
        return product;
    }
    @Override
    public List<Product> getProductByName(String name) {
        logger.info("正在通过名称模糊查询商品: {}", name);
        List<Product> products = productMapper.findByName(name);
        if (products == null){
            logger.warn("未查找到名为{}的商品",name);
            throw new ResourceNotFoundException("Product","name",name);
        }
        return products;
    }

    @Transactional
    @Override
    public Product createProduct(Product product) {
        logger.info("正在创建商品: {}", product.getName());
        int insertedRows = productMapper.insert(product);
        if (insertedRows == 0) {
            logger.error("创建商品失败: {}", product.getName());
            throw new RuntimeException("创建商品失败，请稍后重试");
        }
        return product;
    }

    @Transactional
    @Override
    public Product updateProduct(Product product) {
        logger.info("正在更新商品: id={}", product.getId());
        int updatedRows = productMapper.update(product);
        if (updatedRows == 0) {
            logger.error("更新商品失败: id={}", product.getId());
            throw new ResourceNotFoundException("Product", "id", product.getId());
        }
        return product;
    }

    @Transactional
    @Override
    public void deleteProductById(Integer id) {
        logger.info("正在删除商品: id={}", id);
        int deletedRows = productMapper.deleteById(id);
        if (deletedRows == 0) {
            logger.error("删除商品失败: id={}", id);
            throw new ResourceNotFoundException("Product", "id", id);
        }
    }

    @Override
    public List<Product> getProductByCategoryId(Integer id) {
        logger.info("正在查询分类id = {}的所有子商品",id);
        List<Product> products;
        if(id == 1) {
            products = productMapper.findAll();
            if (products.isEmpty()) {
                logger.warn("没有查询到分类All的所有子商品");
                throw new ResourceNotFoundException("Product","category_id",id);
            }
            return products;
        }
        List<Category> categories = categoryMapper.findCategoryByParentCategoryID(Long.valueOf(id));

        if(categories.isEmpty()){
            products = productMapper.findByCategoryId(id);
            if (products == null) {
                logger.warn("没有查询到分类id = {}的所有子商品",id);
                throw new ResourceNotFoundException("Product","category_id",id);
            }
            return products;
        }
        products = new ArrayList<Product>();
        for(Category category:categories){
            List<Product> tempProducts = productMapper.findByCategoryId(Integer.parseInt(category.getId().toString()));
            products.addAll(tempProducts);
        }
        if (products.isEmpty()){
            logger.warn("没有查询到分类id = {}的所有子商品",id);
            throw new ResourceNotFoundException("Product","category_id",id);
        }
        return products;
    }

    @Override
    public List<CategorySalesDto> getCategorySales() {
        logger.info("Calculating cumulative sales for all categories.");

        List<CategorySalesDto> leafSales = productMapper.findSalesByLeafCategory();
        Map<Long, BigDecimal> leafSalesMap = leafSales.stream()
                .collect(Collectors.toMap(CategorySalesDto::getCategoryId, CategorySalesDto::getTotalSales));

        List<Category> allCategories = categoryMapper.findAll();
        Map<Long, Category> categoryMapById = allCategories.stream()
                .collect(Collectors.toMap(Category::getId, c -> c));

        Map<Long, CategorySalesDto> finalSalesMap = allCategories.stream()
                .collect(Collectors.toMap(
                        Category::getId,
                        c -> new CategorySalesDto(c.getId(), c.getName(), BigDecimal.ZERO)
                ));

        for (Category category : allCategories) {
            BigDecimal directSales = leafSalesMap.getOrDefault(category.getId(), BigDecimal.ZERO);
            if (directSales.compareTo(BigDecimal.ZERO) > 0) {
                Category current = category;
                while (current != null) {
                    finalSalesMap.get(current.getId()).addSales(directSales);
                    if (current.getParentCategoryID() != null) {
                        current = categoryMapById.get(current.getParentCategoryID());
                    } else {
                        current = null;
                    }
                }
            }
        }

        logger.info("Successfully calculated sales for {} categories.", finalSalesMap.size());
        return new ArrayList<>(finalSalesMap.values());
    }

} 